package edu.umd.ion.wavemeter.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import edu.umd.ion.wavemeter.service.DynamicExposureParameters;
import edu.umd.ion.wavemeter.service.ServerParameters;
import edu.umd.ion.wavemeter.service.WavemeterServiceAsync;

public class ExposureParametersWidget extends Composite implements
		BeforeSelectionHandler<Integer> {
	private WavemeterServiceAsync WavemeterService;
	private FlexTable Table;
	private VerticalPanel Vertical;
	private Panel ErrorPanel;
	private HTML ErrorMessage;
	private DynamicExposureParameters ParametersCache;
	private boolean Initialized = false;
	private Button ApplyButton;

	TextBox TBMaxPossible, TBMaxAdj, TBOptimum, TBMinAdj, TBReduceToPercent, TBMaxExposure, TBMinExposure;
	TextBox TBUnderexposedTimeout, TBSecondInterferometerBalance, TBSkipCount;

	
	private native void reload() /*-{
    $wnd.location.reload();
   }-*/;

	private AsyncCallback<DynamicExposureParameters> ExposureParametersCallback = 
			new AsyncCallback<DynamicExposureParameters>() {
		public void onFailure(Throwable caught) {
			try {
				ErrorMessage.setHTML("Command: " + caught.getMessage());
				throw caught;
			} catch (IncompatibleRemoteServiceException e) {
				// this client is not compatible with the server; cleanup and refresh the 
				// browser
				reload();
			} catch (Throwable e) {
				// last resort -- a very unexpected exception
			}
		}

		public void onSuccess(DynamicExposureParameters result) {
			ErrorMessage.setHTML("");
			displayExposureParameters(result);
		}
	};
	
	public void displayExposureParameters(ServerParameters P) {
		try {
			DynamicExposureParameters dp = (DynamicExposureParameters) P;
			if (P!=null) {
				ParametersCache = dp;	
				ApplyButton.setEnabled(dp.isEditable());
				TBMaxPossible.setText( String.valueOf(dp.MaxPossible) );
				TBMaxPossible.setEnabled(dp.isEditable());
				TBMaxAdj.setText( String.valueOf(dp.MaxAdj) );
				TBMaxAdj.setEnabled(dp.isEditable());
				TBOptimum.setText( String.valueOf(dp.Optimum) );
				TBOptimum.setEnabled(dp.isEditable());
				TBMinAdj.setText( String.valueOf(dp.MinAdj) );
				TBMinAdj.setEnabled(dp.isEditable());
				TBReduceToPercent.setText( String.valueOf(dp.ReduceToPercent) );
				TBReduceToPercent.setEnabled(dp.isEditable());
				TBMaxExposure.setText( String.valueOf(dp.MaxExposure) );
				TBMaxExposure.setEnabled(dp.isEditable());
				TBMinExposure.setText( String.valueOf(dp.MinExposure) );
				TBMinExposure.setEnabled(dp.isEditable());
				TBUnderexposedTimeout.setText( String.valueOf(dp.UnderexposedTimeout));
				TBUnderexposedTimeout.setEnabled(dp.isEditable());
				TBSecondInterferometerBalance.setText( String.valueOf(dp.SecondInterferometerBalance));
				TBSecondInterferometerBalance.setEnabled(dp.isEditable());
				TBSkipCount.setText( String.valueOf(dp.SkipCount));
				TBSkipCount.setEnabled(dp.isEditable());
			}
		}
		catch (ClassCastException ex) {}
	}
	
	public void queryExposureParameters() {
			WavemeterService.getExposureParameters(ExposureParametersCallback);
	}
	
	public void applyExposureParameters() {
		DynamicExposureParameters P = ParametersCache;
		P.MaxPossible = Integer.valueOf( TBMaxPossible.getText() );
		P.MaxAdj = Integer.valueOf( TBMaxAdj.getText() );
		P.Optimum = Integer.valueOf( TBOptimum.getText() );
		P.MinAdj = Integer.valueOf( TBMinAdj.getText() );
		P.ReduceToPercent = Integer.valueOf( TBReduceToPercent.getText() );
		P.MaxExposure = Integer.valueOf( TBMaxExposure.getText() );
		P.MinExposure = Integer.valueOf( TBMinExposure.getText() );
		P.UnderexposedTimeout = Integer.valueOf( TBUnderexposedTimeout.getText() );
		P.SecondInterferometerBalance = Double.valueOf( TBSecondInterferometerBalance.getText() );
		P.SkipCount = Integer.valueOf( TBSkipCount.getText());
		WavemeterService.setExposureParameters(P,ExposureParametersCallback);
	}

	ClickHandler ApplyHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			applyExposureParameters();
		}
	};
	
	public ExposureParametersWidget(WavemeterServiceAsync cb, Panel errorPanel ) {
		WavemeterService = cb;
		ErrorPanel = errorPanel;
			
		Vertical = new VerticalPanel();
		initWidget(Vertical);
	}

	public void initialize() {
		HorizontalPanel Horiz = new HorizontalPanel();
		ApplyButton = new Button("Apply",ApplyHandler);
		Horiz.add( new Button("Refresh",new ClickHandler() {
			public void onClick(ClickEvent event) {
				queryExposureParameters();
			}}));
		Horiz.add( ApplyButton );
		
		Table = new FlexTable();
		Table.setHTML(0, 0, "Intensity Overexposed Threshold");
		TBMaxPossible = new TextBox();
		TBMaxPossible.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(0,1, TBMaxPossible);
		Table.setHTML(1,0, "Intensity Upper Adjust Limit");
		TBMaxAdj = new TextBox();
		TBMaxAdj.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(1,1, TBMaxAdj);
		Table.setHTML(2,0, "Intensity Optimum");
		TBOptimum = new TextBox();
		TBOptimum.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(2,1, TBOptimum);
		Table.setHTML(3,0, "Intensity Lower Adjust Limit");
		TBMinAdj = new TextBox();
		TBMinAdj.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(3,1, TBMinAdj);
		Table.setHTML(4,0, "Exposure Reduction to [%]");
		TBReduceToPercent = new TextBox();
		TBReduceToPercent.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(4,1, TBReduceToPercent);
		Table.setHTML(5,0, "Maximum Exposure");
		TBMaxExposure = new TextBox();
		TBMaxExposure.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(5,1,TBMaxExposure);
		Table.setHTML(6,0, "Minimum Exposure");
		TBMinExposure = new TextBox();
		TBMinExposure.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(6,1, TBMinExposure);
		Table.setHTML(7,0, "Underexposed Timeout [ms]");
		TBUnderexposedTimeout = new TextBox();
		TBUnderexposedTimeout.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(7,1, TBUnderexposedTimeout);
		Table.setHTML(8,0,"Second Interferometer Balance");
		TBSecondInterferometerBalance = new TextBox();
		TBSecondInterferometerBalance.addKeyPressHandler(new KeyoardOnlyNumbers(ApplyHandler) );
		Table.setWidget(8,1,TBSecondInterferometerBalance);
		Table.setHTML(9,0,"Skip Count");
		TBSkipCount = new TextBox();
		TBSkipCount.addKeyPressHandler(new KeyoardOnlyDigits(ApplyHandler) );
		Table.setWidget(9, 1, TBSkipCount);
		ErrorMessage = new HTML();
		ErrorPanel.add(ErrorMessage);
		Vertical.add(Horiz);
		Vertical.add(Table);
		Initialized = true;
	}
	
	@Override
	public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
		if (!Initialized) {
			initialize();
		}
		queryExposureParameters(); 
	}

}
